#include <string.h>
#include "door_common.h"
#include "gkt_door.h"
#include "gkt_backboard.h"

#if defined(GKT_CONFIG_DOOR_LOCK_ENABLE) && GKT_CONFIG_DOOR_LOCK_ENABLE \
	&& defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC \
	&& (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION) \
	&& defined(GKT_CONFIG_DOOR_KEY_ENABLE) && GKT_CONFIG_DOOR_KEY_ENABLE

enum {
	DOOR_KEY_OP_INFO = 0,
	DOOR_KEY_OP_MAX
};

typedef struct {
	uint32_t	key_detect_bits;
	uint32_t	mask_bits;
} door_key_bb_s;
static door_key_bb_s s_door_key_bb;

enum {
	DOOR_KEY_INFO_VALUE = GKT_BB_APP_PACKET_MINSIZE,
	DOOR_KEY_INFO_ACTION,
	DOOR_KEY_INFO_MAX
};

enum {
	DOOR_KEY_ACTION_RELEASE = 0,
	DOOR_KEY_ACTION_PRESS,
	DOOR_KEY_ACTION_MAX
};

static void door_key_module_notify(int type, 
				const uint8_t *data, int length_retval)
{
	uint8_t opcode, key_value, key_action;
	uint32_t key_mask;

	if ((GKT_BB_NOTIFY_PEER == type)
		&& (length_retval >= DOOR_KEY_ACTION_MAX))
	{
		opcode = data[GKT_BB_APP_PACKET_OPCODE];
		if (DOOR_KEY_OP_INFO == opcode) {
			key_value = data[DOOR_KEY_INFO_VALUE];
			if (key_value < GKT_DOOR_KEY_MAX) {
				key_action = data[DOOR_KEY_INFO_ACTION];
				gkt_info("door_key_module: key(%u-%u), bits(0x%x-0x%x)\n",
					key_value, key_action, s_door_key_bb.mask_bits, 
					s_door_key_bb.key_detect_bits);

				key_mask = 1U << key_value;
				if (!(s_door_key_bb.mask_bits & key_mask)) {
					if ((DOOR_KEY_ACTION_PRESS == key_action)
						&& !(s_door_key_bb.key_detect_bits & key_mask))
					{
						s_door_key_bb.key_detect_bits |= key_mask;
						door_inner_notify(GKT_DOOR_NOTIFY_KEY, key_value);
					}
					else if (DOOR_KEY_ACTION_RELEASE == key_action)
						s_door_key_bb.key_detect_bits &= ~key_mask;
				}
			}
			else
				gkt_error("door_key_module: invalid key %u\n", key_value);
		}
		else
			gkt_error("door_key_module: invalid opcode %u\n", opcode);
	}
}

int door_key_init(void)
{
	s_door_key_bb.key_detect_bits = 0;
	s_door_key_bb.mask_bits = 0;
	gkt_backboard_register_module(GKT_BB_MODULE_DOOR_KEY,
			DOOR_KEY_OP_MAX,door_key_module_notify);

	return GKT_SUCCESS;
}

void gkt_door_key_mask(uint32_t mask_bits)
{
	gkt_info("door_key: mask_bits= 0x%x\n", mask_bits);
	s_door_key_bb.mask_bits = mask_bits;
	s_door_key_bb.key_detect_bits &= ~mask_bits;
}

gkt_door_key_e gkt_door_key_get_wakeup_key(void)
{
	return GKT_DOOR_KEY_MAX;
}

int gkt_door_key_is_detected(gkt_door_key_e key)
{
	return (s_door_key_bb.key_detect_bits & (1U << key)) ? 1 : 0;
}

#endif

